package com.chen.blue.service.business.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.chen.blue.annotation.permission.DataPermission;
import com.chen.blue.converter.business.*;
import com.chen.blue.converter.business.ContestApplyConverter;
import com.chen.blue.converter.business.ContestApplyConverter;
import com.chen.blue.converter.business.ContestApplyConverter;
import com.chen.blue.dictionary.AuditDict;
import com.chen.blue.domain.delete.business.ContestApplyDelete;
import com.chen.blue.domain.dto.business.ContestApplyDto;
import com.chen.blue.domain.dto.business.ContestPersonInfoDto;
import com.chen.blue.domain.dto.business.update.ContestApplyDtoEdit;
import com.chen.blue.domain.model.business.*;
import com.chen.blue.domain.model.business.ContestApplyModel;
import com.chen.blue.domain.model.business.ContestApplyModel;
import com.chen.blue.domain.query.business.ContestApplyQuery;
import com.chen.blue.domain.query.system.DeptQuery;
import com.chen.blue.domain.vo.business.ContestApplyVo;
import com.chen.blue.domain.vo.business.ContestApplyVo;
import com.chen.blue.domain.vo.business.ContestApplyVo;
import com.chen.blue.domain.vo.system.DeptVo;
import com.chen.blue.exception.e.DtoNullException;
import com.chen.blue.mapper.business.ContestApplyMapper;
import com.chen.blue.result.DataResult;
import com.chen.blue.service.business.IContestApplyActiveService;
import com.chen.blue.service.business.IContestApplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.blue.service.business.IContestPersonInfoHistoryService;
import com.chen.blue.service.business.IContestPersonInfoService;
import com.chen.blue.service.candidate.CandidateInfoService;
import com.chen.blue.service.security.SecurityService;
import com.chen.blue.service.system.IDeptService;
import com.chen.blue.utils.PageInfoUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 竞赛表 服务实现类
 * </p>
 *
 * @author CLT
 * @since 2024-05-26
 */
@Service("iContestApplyService")
public class IContestApplyServiceImpl extends ServiceImpl<ContestApplyMapper, ContestApplyModel> implements IContestApplyService {

    @Resource
    private IContestPersonInfoService iContestPersonInfoService;

    @Resource
    private IContestApplyActiveService iContestApplyActiveService;

    @Resource
    private IDeptService iDeptService;

    @Override
    public boolean addContestApply(ContestApplyDto contestApplyDto) throws DtoNullException {

        if (Objects.isNull(contestApplyDto)) {
            throw new DtoNullException("参数为空");
        }

        return super.save(ContestApplyConverter.dtoToModel(contestApplyDto));

    }

    @Override
    public boolean deleteContestApply(ContestApplyDelete contestApplyDelete) throws DtoNullException {

        if (Objects.isNull(contestApplyDelete)) {
            throw new DtoNullException("参数为空");
        }

        Map<String, Object> wrap = new HashMap<>();
        if (Objects.nonNull(contestApplyDelete.getId())) {
            wrap.put("id", contestApplyDelete.getId());
        }

        return Objects.nonNull(contestApplyDelete.getIds()) ? super.removeByIds(contestApplyDelete.getIds()) : super.removeByMap(wrap);

    }

    @Override
    public boolean updateContestApplyById(ContestApplyDtoEdit contestApplyDtoEdit) throws DtoNullException {

        if (Objects.isNull(contestApplyDtoEdit)) {
            throw new DtoNullException("参数为空");
        }

        CandidateInfoService.setUpdater(contestApplyDtoEdit);

        return super.updateById(ContestApplyConverter.dtoEditToModel(contestApplyDtoEdit));

    }

    /**
     * 为竞赛表添加参赛人员信息
     *
     * @param applyId                  apply_id
     * @param contestPersonInfoDtoList
     * @return
     * @throws DtoNullException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addRelationPersonInfo(Long applyId, List<ContestPersonInfoDto> contestPersonInfoDtoList) throws DtoNullException {

        if (Objects.isNull(applyId) || Objects.isNull(contestPersonInfoDtoList) || contestPersonInfoDtoList.isEmpty()) {
            throw new DtoNullException("参数为空");
        }
        ContestApplyModel tempContestApplyModel = super.getById(applyId);
        Long relation = Objects.nonNull(tempContestApplyModel) ? tempContestApplyModel.getRelation() : null;
        LambdaQueryWrapper<ContestApplyActiveModel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContestApplyActiveModel::getId, relation);
        // 校验是否可以进行操作(只有处于人员信息填报阶段才可操作)
        validateUpdateOrAddEnabled(relation);

        List<ContestPersonInfoDto> data = contestPersonInfoDtoList.stream().peek(obj -> {
            obj.setApplyId(applyId);
            obj.setActiveId(relation);
        }).collect(Collectors.toList());

        List<ContestPersonInfoModel> contestPersonInfoModelList = ContestPersonInfoConverter.dtoListToModelList(data);

        CandidateInfoService.setCreator(contestPersonInfoModelList);
        CandidateInfoService.setUpdater(contestPersonInfoModelList);

        return iContestPersonInfoService.saveOrUpdateBatch(contestPersonInfoModelList);

    }


    @DataPermission
    @Override
    public DataResult<List<ContestApplyVo>> queryContestApply(ContestApplyQuery contestApplyQuery) throws DtoNullException {

        if (Objects.isNull(contestApplyQuery)) {
            throw new DtoNullException("查询条件为空");
        }

        LambdaQueryWrapper<ContestApplyModel> wrapper = new LambdaQueryWrapper<>();
        if (Objects.nonNull(contestApplyQuery.getPageNo()) && Objects.nonNull(contestApplyQuery.getPageSize())) {
            PageHelper.startPage(contestApplyQuery.getPageNo(), contestApplyQuery.getPageSize());
        }
        wrapper.orderByDesc(ContestApplyModel::getCreateTime);

        List<ContestApplyModel> contestApplyModelList = super.list(wrapper);
        PageInfo<ContestApplyModel> pageInfo = new PageInfo<>(contestApplyModelList);
        PageHelper.clearPage();

        /**
         * 统一结果返回
         */
        DataResult<List<ContestApplyVo>> dataResult = new DataResult<>();
        dataResult.setData(ContestApplyConverter.modelToVoList(pageInfo.getList()));
        PageInfoUtil.setPageInfo(dataResult, pageInfo);

        return dataResult;

    }

    @Override
    public DataResult<Map<String, Object>> queryContestApplyById(Long applyId) throws DtoNullException {

        if (Objects.isNull(applyId)) {
            throw new DtoNullException("ID为空");
        }

        // 竞赛及其相关人员信息
        Map<String, Object> data = new HashMap<>();
        data.put("contest", ContestApplyConverter.modelToVo(super.getById(applyId)));
        data.put("persons", iContestPersonInfoService.queryByApplyId(applyId).getResult());

        DataResult<Map<String, Object>> dataResult = new DataResult<>();
        dataResult.setData(data);

        return dataResult;

    }

    @Override
    public DataResult<List<DeptVo>> queryDept(DeptQuery deptQuery, boolean isTree) throws DtoNullException {

        return iDeptService.queryDept(deptQuery, isTree);

    }

    /**
     * 验证是否可操作
     *
     * @param activeId
     */
    protected void validateUpdateOrAddEnabled(Long activeId) throws DtoNullException {

        if (Objects.nonNull(activeId)) {

            ContestApplyActiveModel temp = iContestApplyActiveService.getById(activeId);

            if (Objects.nonNull(temp)) {
                if (!(AuditDict.STAGE_STAGE_SECOND.equals(temp.getStageCurrent()) &&
                        AuditDict.ROLE_INNER_NO.equals(temp.getPersonAudit()) &&
                        AuditDict.AUDIT_STATUS_NO.equals(temp.getAuditStatus()) &&
                        AuditDict.CURRENT_STATUS_NOT_REPORT.equals(temp.getStageCurrentStatus()))) {

                    throw new DtoNullException("当前流程状态不可操作");

                }
            }

        }

    }

}
